#!/usr/bin/env python
# coding=utf-8
from datetime import datetime
from flask import current_app
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from fileshare.extensions import db
import random
import string
import uuid
import os


class Admin(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)  # 添加索引，限定唯一
    username = db.Column(db.String(20), unique=True, index=True)
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean, default=False, comment='是否认证')
    last_seen = db.Column(
        db.DateTime(), default=datetime.utcnow, comment='最后活动时间')
    filenames = db.Column(db.String(32), unique=True,
                          index=True, comment='个人文件夹')

    fileshare = db.relationship("FileShare", backref="admin")

    @property
    def password(self):
        raise AttributeError('密码不是一个可读的属性')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def generate_confirmation_token(self, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'confirm': self.id})

    def confirm(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('confirm') != self.id:
            return False
        self.confirmed = True
        db.session.add(self)
        db.session.commit()
        return True

    def generate_reset_token(self, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'reset': self.id})

    def reset_password(self, token, new_password):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('reset') != self.id:
            return False
        self.password = new_password
        db.session.add(self)
        db.session.commit()
        return True

    def ping(self):
        # 最近一次活动
        self.last_seen = datetime.utcnow()
        db.session.add(self)
        db.session.commit()

    def get_filenames(self):
        # 返回一个文件名,基于随机数
        letter = string.ascii_letters+string.digits
        return ''.join(random.sample(letter, 10))

    def get_filenames_all(self):
        # 返回用户完整路径
        if current_app.config['FILESHARE_IS_NETDISC']:
            filenames = os.path.join(
                current_app.config['FILESHARE_WORKDIR'], self.filenames)
            if not os.path.exists(filenames):
                os.mkdir(filenames)
            return filenames
        else:
            if not os.path.exists(current_app.config['FILESHARE_WORKDIR']):
                os.mkdir(current_app.config['FILESHARE_WORKDIR'])
            return current_app.config['FILESHARE_WORKDIR']


class FileShare(db.Model):
    __tablename__ = 'fileshare'
    __table_args__ = {'comment': '分享文件表'}

    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(128))
    filepath = db.Column(db.String(128), comment='文件路径')
    getcode = db.Column(db.String(60), comment='提取码')
    validdate = db.Column(db.String(60), comment='过期时间')
    filesize = db.Column(db.String(32), comment='文件大小')

    username = db.Column(db.String(20), db.ForeignKey(
        'admin.username'), index=True)

    def get_code(self):
        # 返回一个code,基于uuid
        uid = str(uuid.uuid1())
        return ''.join(uid.split('-'))

    def to_json(self):
        json_post = {
            'id': self.id,
            'code': self.code,
            'filepath': self.filepath,
            'getcode': self.getcode,
            'validdate': self.validdate,
            'filesize': self.filesize,
        }
        return json_post


class FileInfo(db.Model):
    __tablename__ = 'fileinfo'
    __table_args__ = {'comment': '文件信息表'}

    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(128))
    filepath = db.Column(db.String(128), comment='文件路径')
    filetype = db.Column(db.String(60), comment='文件类型')
    filename = db.Column(db.String(60), comment='文件名')
    filesize = db.Column(db.String(32), comment='文件大小')
    filemodtime = db.Column(db.DateTime(), comment='修改时间')
    isfolder = db.Column(db.Boolean, default=False, comment='是否文件夹')
    power = db.Column(db.String(32), comment='权限')
    username = db.Column(db.String(20), db.ForeignKey(
        'admin.username'), index=True)

    def get_code(self):
        # 返回一个code,基于uuid
        uid = str(uuid.uuid1())
        return ''.join(uid.split('-'))

    @property
    def filetypes(self):
        return self.filetype

    @filetypes.setter
    def filetypes(self, path):
        fileCoding = os.path.splitext(path)[1][1:]
        if fileCoding in ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'svg', 'ico']:
            self.filetype = 'image'
        if fileCoding in ['txt', 'xls', 'xlsx', 'doc', 'docx', 'pdf', 'ppt', 'pptx']:
            self.filetype = 'document'
        if fileCoding in ['mp4', 'm2v', 'mkv', 'rmvb', 'wmv', 'avi', 'flv', 'mov', 'm4v']:
            self.filetype = 'video'
        if fileCoding in ['torrent']:
            self.filetype = 'torrent'
        if fileCoding in ['mp3', 'wav', 'wmv']:
            self.filetype = 'radio'
        if not self.filetype:
            self.filetype = 'other'

    def to_json(self):
        json_post = {
            'id': self.id,
            'code': self.code,
            'filepath': self.filepath,
            'filetype': self.filetype,
            'filename': self.filename,
            'filesize': self.filesize,
            'filemodtime': self.filemodtime,
            'isfolder': self.isfolder,
            'power': self.power,
            'username': self.username,
        }
        return json_post


class RecycleBin(db.Model):
    __tablename__ = 'recyclebin'
    __table_args__ = {'comment': '文件回收站'}

    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(128))
    originalpath = db.Column(db.String(128), comment='原位置')
    filepath = db.Column(db.String(128), comment='回收站文件路径')
    filename = db.Column(db.String(60), comment='回收站文件名')
    filenames = db.Column(db.String(60), comment='回收站文件夹',
                          default='__recyclebin')
    filemodtime = db.Column(
        db.DateTime(), comment='删除时间', default=datetime.utcnow)
    filesize = db.Column(db.String(32), comment='文件大小')
    filemodtime = db.Column(db.DateTime(), comment='修改时间')
    isfolder = db.Column(db.Boolean, default=False, comment='是否文件夹')
    power = db.Column(db.String(32), comment='权限')
    validdate = db.Column(db.String(60), comment='有效日期')
    username = db.Column(db.String(20), db.ForeignKey(
        'admin.username'), index=True)

    def get_code(self):
        # 返回一个code,基于uuid
        uid = str(uuid.uuid1())
        return ''.join(uid.split('-'))

    def to_json(self):
        json_post = {
            'id': self.id,
            'code': self.code,
            'originalpath': self.originalpath,
            'filepath': self.filepath,
            'filetype': self.filetype,
            'filename': self.filename,
            'filenames': self.filenames,
            'filesize': self.filesize,
            'filemodtime': self.filemodtime,
            'isfolder': self.isfolder,
            'power': self.power,
            'username': self.username,
        }
        return json_post

    def get_filenames_all(self):
        # 返回回收站完整路径
        filenames = os.path.join(
            current_app.config['FILESHARE_WORKDIR'], '__recyclebin')
        if not os.path.exists(filenames):
            os.mkdir(filenames)
        return filenames
